package top.glkj.hms.service.impl;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import top.glkj.hms.algorithm.Order;
import top.glkj.hms.dao.ActivityDao;
import top.glkj.hms.dao.HotelFacilitiesDao;
import top.glkj.hms.dao.OrderFormDao;
import top.glkj.hms.entity.Activity;
import top.glkj.hms.entity.OrderForm;
import top.glkj.hms.entity.Room;
import top.glkj.hms.entity.User;
import top.glkj.hms.service.OrderService;
import top.glkj.hms.service.RoomService;
import top.glkj.hms.service.UserService;
import top.glkj.hms.utils.*;

import javax.persistence.criteria.Path;
import javax.persistence.criteria.Predicate;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author : xgl
 * @version : 0.0.1
 * @date :2021/1/7 0:27
 */
@Service
@Slf4j
public class OrderServiceImpl implements OrderService {
    private final OrderFormDao orderFormDao;
    private final ActivityDao activityDao;
    private final HotelFacilitiesDao hotelFacilitiesDao;
    private final RoomService roomService;
    private final UserService userService;

    public OrderServiceImpl(OrderFormDao orderFormDao, ActivityDao activityDao, HotelFacilitiesDao hotelFacilitiesDao,
                            RoomService roomService, UserService userService) {
        this.orderFormDao = orderFormDao;
        this.activityDao = activityDao;
        this.hotelFacilitiesDao = hotelFacilitiesDao;
        this.roomService = roomService;
        this.userService = userService;
    }

    /**
     * 添加订单
     *
     * @param orderForm 订单
     * @return 结果
     */
    @Override
    public Result addOrderForm(OrderForm orderForm) {
        orderForm.setCreateTime(new Date());
        orderForm.setUpdateTime(new Date());
        //orderForm.setCreateUserId(getCurrentUser().getId());
        orderForm.setDel(false);
        //orderForm.setUpdateUserId(getCurrentUser().getId());
        orderForm.setOrderNumber(Order.getOrderNumber((User) userService.getOne(orderForm.getInsertUser()).getObject(),orderForm.getCreateTime()));
        return save(orderForm);
    }

    /**
     * 更新订单
     *
     * @param orderForm 订单
     * @return 订单
     */
    @Override
    public Result updateOrderForm(OrderForm orderForm) {
        return null;
    }

    /**
     * 获取所有用户，按分页方式
     *
     * @return List<T>
     */
    @Override
    public Result getAll() {
        List<OrderForm> all = orderFormDao.findAll();
       return getNotEmptyAll(all);
    }

    /**
     * 获取所有用户，按分页方式
     *
     * @param id id
     * @return T t
     */
    @Override
    public Result getOne(Long id) {
        OrderForm orderForm = orderFormDao.findById(id).orElse(null);
        return getNotNullEntity(orderForm);
    }

    /**
     * 修改或者保存
     *
     * @param orderForm T t
     * @return true or false
     */
    @Override
    public Result save(OrderForm orderForm) {
        try {
            OrderForm save = orderFormDao.save(orderForm);
            return ResultFactory.isSuccess(StaticValue.SUCCESS_MESSAGE, save);
        } catch (Exception e) {
            log.error(e.getMessage());
            return ResultFactory.isError(StaticValue.ERROR_MESSAGE, null);
        }
    }

    /**
     * 彻底从数据库中删除实体{T}
     *
     * @param orderForm T t
     * @return true or false
     */
    @Override
    public Result delete(OrderForm orderForm) {
        try {
            orderFormDao.delete(orderForm);
            return ResultFactory.isSuccess(StaticValue.DELETE_DATA_SUCCESS);
        } catch (Exception e) {
            log.error(e.getMessage());
            return ResultFactory.isError(StaticValue.DELETE_DATA_ERROR,e);
        }
    }

    /**
     * 标记删除
     *
     * @param orderForm T t
     * @return true or false
     */
    @Override
    public Result remove(OrderForm orderForm) {
        orderForm.setDel(true);
        orderForm.setStatus(Status.Delete);
        Result save = save(orderForm);
        if (ResultFactory.isSuccess(save)) {
            return ResultFactory.isSuccess(StaticValue.DELETE_DATA_SUCCESS, save);
        } else {
            return ResultFactory.isException(StaticValue.DELETE_DATA_ERROR);
        }
    }



    /**
     * 分页查询订单
     *
     * @param page 页码
     * @param size 页面大小
     * @return 订单
     */
    @Override
    public Result getAllOrderFormByPageAndSize(int page, int size) {
        GlUtils<OrderForm, OrderFormDao> glUtils = new GlUtils<>();
        return glUtils.getAllByPageAndSize(page,size,orderFormDao);
    }

    /**
     * 分页查询订单
     *
     * @param page   页码
     * @param size   页面大小
     * @param status
     * @return 订单
     */
    @Override
    public Result getAllOrderFormByPageAndSizeAndStatus(int page, int size, Status status) {
        Pageable pageable = PageRequest.of(pageValue(page)-1, sizeValue(size));
        Specification<OrderForm> specification = (root, query, cb) -> {
            /* 1、获取比较属性 */
            Path<Object> status1 = root.get("status");
            return  cb.equal(status1, status);
        };
        return getNotNullPageResult(orderFormDao.findAll(specification,pageable));
    }

    /**
     * 查询订单
     *
     * @param status
     * @return 订单
     */
    @Override
    public Result getAllOrderFormByStatus(Status status) {
        Specification<OrderForm> specification = (root, query, cb) -> {
            /* 1、获取比较属性 */
            Path<Object> status1 = root.get("status");
            return  cb.equal(status1, status);
        };
        List<OrderForm> all = orderFormDao.findAll(specification);
        return all.isEmpty() ? ResultFactory.isException(StaticValue.DATA_NOT_FOUND) : ResultFactory.isSuccess(StaticValue.GET_DATA_SUCCESS, all);
    }

    /**
     * 分页搜索查询订单
     *
     * @param page    页码
     * @param size    页面大小
     * @param argName 参数名
     * @param value   参数值
     * @return 订单
     */
    @Override
    public Result getAllOrderFormByPageAndSizeAndArg(int page, int size, String argName, String value) {
        GlUtils<OrderForm, OrderFormDao> glUtils = new GlUtils<>();
        return glUtils.getAllByPageAndSizeAndArgs(page,size,argName,value,orderFormDao);
    }

    /**
     * 分页搜索多条件查询订单
     *
     * @param page 页码
     * @param size 页面大小
     * @param args 参数键值对
     * @return 订单
     */
    @Override
    public Result getAllOrderFormByPageAndSizeAndArgs(int page, int size, Map<String, String> args) {
        GlUtils<OrderForm, OrderFormDao> glUtils = new GlUtils<>();
        return glUtils.getAllByPageAndSizeAndAnyArgs(page,size,args,orderFormDao);
    }

    /**
     * 保存活动
     *
     * @param activity 活动
     * @return 结果
     */
    @Override
    public Result saveActivity(Activity activity) {
        try {
            Activity save = activityDao.save(activity);
            return ResultFactory.isSuccess(StaticValue.SUCCESS_MESSAGE, save);
        } catch (Exception e) {
            log.error(e.getMessage());
            return ResultFactory.isError(StaticValue.ERROR_MESSAGE, null);
        }
    }

    /**
     * 添加活动
     *
     * @param activity 活动
     * @return 结果
     */
    @Override
    public Result addActivity(Activity activity) {
        activity.setCreateTime(new Date());
        activity.setDel(false);
        activity.setCreateUserId(getCurrentUser().getId());
        activity.setUpdateTime(new Date());
        activity.setUpdateUserId(getCurrentUser().getId());
        return saveActivity(activity);
    }

    /**
     * 更新活动
     *
     * @param activity 活动
     * @return 结果
     */
    @Override
    public Result updateActivity(Activity activity) {
        activity.setUpdateTime(new Date());
        activity.setUpdateUserId(getCurrentUser().getId());
        return saveActivity(activity);
    }

    /**
     * 删除活动
     *
     * @param activity 活动
     * @return 结果
     */
    @Override
    public Result deleteActivity(Activity activity) {
        try {
            activityDao.delete(activity);
            return ResultFactory.isSuccess(StaticValue.DELETE_DATA_SUCCESS);
        } catch (Exception e) {
            log.error(e.getMessage());
            return ResultFactory.isError(StaticValue.DELETE_DATA_ERROR,e);
        }
    }

    /**
     * 移除活动
     *
     * @param activity 活动
     * @return 结果
     */
    @Override
    public Result removeActivity(Activity activity) {
        activity.setDel(true);
        return updateActivity(activity);
    }

    /**
     * 获取活动
     *
     * @param id id
     * @return 结果
     */
    @Override
    public Result getActivity(long id) {
        Activity byId = activityDao.findById(id).orElse(null);
        return getNotNullBaseEntity(byId);
    }

    /**
     * 获取所有活动
     *
     * @return 所有活动
     */
    @Override
    public Result getAllActivity() {
        List<Activity> all = activityDao.findAll();
        return all.isEmpty() ? ResultFactory.isException(StaticValue.DATA_NOT_FOUND) : ResultFactory.isSuccess(StaticValue.GET_DATA_SUCCESS, all);
    }

    /**
     * 获取一个活动根据房间
     *
     * @param room 房间
     * @return 房间的活动
     */
    @Override
    public Result getActivityByRoom(Room room) {
        // TODO: 2021/1/7
        return null;
    }

    /**
     * 获取所有活动根据房间
     *
     * @param room 房间
     * @return 房间的活动
     */
    @Override
    public Result getAllActivityByRoom(Room room) {
        // TODO: 2021/1/7
        return null;
    }

    /**
     * 获取所有活动根据页码和页面大小
     *
     * @param page 页码
     * @param size 页面大小
     * @return 活动
     */
    @Override
    public Result getAllActivityByPageAndSize(int page, int size) {
       GlUtils<Activity,ActivityDao> glUtils = new GlUtils<>();
        return glUtils.getAllByPageAndSize(page,size,activityDao);
    }

    /**
     * 获取所有活动根据页码和页面大小
     *
     * @param page      页码
     * @param size      页面大小
     * @param argName   参数名
     * @param valueName 参数值
     * @return 活动
     */
    @Override
    public Result getAllActivityByPageAndSizeArg(int page, int size, String argName, String valueName) {
        GlUtils<Activity,ActivityDao> glUtils = new GlUtils<>();
        return glUtils.getAllByPageAndSizeAndArgs(page,size,argName,valueName,activityDao);
    }

    /**
     * 获取所有活动根据页码和页面大小
     *
     * @param page 页码
     * @param size 页面大小
     * @param args 搜索参数
     * @return 活动
     */
    @Override
    public Result getAllActivityByPageAndSizeArgs(int page, int size, Map<String, String> args) {
        GlUtils<Activity,ActivityDao> glUtils = new GlUtils<>();
        return glUtils.getAllByPageAndSizeAndAnyArgs(page,size,args,activityDao);
    }

    /**
     * @return
     * todo
     */
    @Override
    public Result getAllOrderByUser() {
        return null;
    }

    /**
     * @return
     * todo
     */
    @Override
    public Result addOrderByUser() {
        return null;
    }

    @Override
    public Result getAllOrderFormByPageAndSizeIsNotFinnish(int page, int size) {
        Pageable pageable = PageRequest.of(pageValue(page)-1,sizeValue(size));
        Specification<OrderForm> specification = (root, query, cb) -> {
            /* 1、获取比较属性 */
            Path<Object> status1 = root.get("status");
            Predicate notEqual = cb.notEqual(status1, Status.Finnish);
            Predicate notEqual1 = cb.notEqual(status1, Status.ToStay);
            return cb.and(notEqual,notEqual1);
        };
        return getNotNullPageResult(orderFormDao.findAll(specification,pageable));

    }

    @Override
    public Result getOrderByOrderNumber(String number) {
        return getNotNullEntity(orderFormDao.findOrderFormByOrderNumber(number));
    }
}
